/*
 * Copyright (c) 2022，公司名称
 * All rights reserved.
 * 文件名称：high_uart.c
 * 摘要：高边串口
 * 当前版本：V1.0.0,WCD,2023/1/10,初版
 * 历史版本：Vx.x.x，编写者/修改者，修改时间，修改内容（重大发布时，总结重点变更内容）
 */

#include "low_includes.h"
/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓应用层数据定义开始↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
#if 1

/*600k = 4016*/
#define NTC_OPEN (4016u)
/*100 = 34*/
#define NTC_SHORT (34u)

static uint16_t ADC0_BUFF[ADC0_BUFF_NUM][ADC0_BUFF_LEN];
static uint16_t ADC0_SampleCount;          /* 采样计数 */
static uint16_t ADC0_CompleteFlag;         /* 1:一个采集序列完成 */
ADC_ORIG_DATA_DEF ADC_OrgiData;            /* ADC 采样原始数据 */
low_ADC_ORIG_DATA_struct low_ADC_OrgiData; /* ADC 采样原始数据 */
void low_AnalSiglPro_CalculSum(void);
#endif
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑应用层数据定义结束↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/
typedef struct
{
  PORT_ID_t PORT;
  /*!< Configure ADC differential mode
      - ADC_SINGLE_MODE (0): ADC single mode
      - ADC_DIFF_MODE (1): ADC differential mode */

  PORT_GPIONO_t GPIO;
  /*!< Configure ADC positive channel
      - ADC_P_CH0 (0):   ADC Positive channel 0
      - ......
      - ADC_P_CH20 (20): ADC Positive channel 20 */

  PORT_PinMuxFunc_t PT;
  /*!< Configure ADC negtive channel
      - ADC_N_CH0 (0):   ADC Negtive channel 0
      - ADC_N_CH1 (1):   ADC Negtive channel 1
      - ADC_N_CH2 (2):   ADC Negtive channel 2
      - ADC_N_VSS (3):   ADC Negtive connected with VSS
   */
} PORT_ADC_Config_t;
/*Sample result with channel information */
static uint32_t adcswResult[4][10] = {0};
/*Sample data value */
static volatile uint16_t dataswResult[4][10] = {0};
/*Sample channel value */
static volatile uint16_t chswResult[4][10] = {0};
static channel_ADC channel = ADC_CH4;
ADC_Config_t adcCfg =
    {
        ADC_RESOLUTION_12BIT,  /* ADC 12-bit resolution */
        ADC_VREF_INTERNAL,     /* Internal Vref_H to 5V, Vref_L to 0V reference */
        ADC_NORMAL_SW_TRIGGER, /* Software trigger select */
        ADC_CONVERSION_SINGLE, /* ADC single conversion */
        ADC_AVGS_8,            /* 8 times average for each conversion*/
        200                    /* Set the time interval between two samples when average is enabled or
                      in continues mode. Please refer to STS definition in RM to see the constraint */
};
PORT_ADC_Config_t port_adc[4] =
    {
              {
            PORT_B,        /* Single-Ended Mode Selected */
            GPIO_0,        /* Single mode, channel[7] and vssa */
            PTB0_ADC0_CH4, /* Single mode, N-channel donn't need to configure */
        },
                {
            PORT_C,          /* Single-Ended Mode Selected */
            GPIO_14,         /* Single mode, channel[7] and vssa */
            PTC14_ADC0_CH12, /* Single mode, N-channel donn't need to configure */
        },
        
        {
            PORT_B,        /* Single-Ended Mode Selected */
            GPIO_2,        /* Single mode, channel[7] and vssa */
            PTB2_ADC0_CH6, /* Single mode, N-channel donn't need to configure */
        },
        {
            PORT_A,        /* Single-Ended Mode Selected */
            GPIO_7,        /* Single mode, channel[7] and vssa */
            PTA7_ADC0_CH3, /* Single mode, N-channel donn't need to configure */
        }

        };
ADC_ChannelConfig_t adcswChannelCfg[4] =
    {
        {
            ADC_SINGLE_MODE, /* Single-Ended Mode Selected */
            ADC_P_CH4,       /* Single mode, channel[7] and vssa */
            ADC_N_NONE,      /* Single mode, N-channel donn't need to configure */
        },
        {
            ADC_SINGLE_MODE, /* Single-Ended Mode Selected */
            ADC_P_CH12,      /* Single mode, channel[7] and vssa */
            ADC_N_NONE,      /* Single mode, N-channel donn't need to configure */
        },
        {
            ADC_SINGLE_MODE, /* Single-Ended Mode Selected */
            ADC_P_CH6,       /* Single mode, channel[7] and vssa */
            ADC_N_NONE,      /* Single mode, N-channel donn't need to configure */
        },
        {
            ADC_SINGLE_MODE, /* Single-Ended Mode Selected */
            ADC_P_CH3,       /* Single mode, channel[7] and vssa */
            ADC_N_NONE,      /* Single mode, N-channel donn't need to configure */
        }
      };
void adc_sw_tcomp_cb(void)
{
  uint32_t i = 0;
  if (NO == ADC0_CompleteFlag)
  {
    /*Get sample result, suggest to discard the first sampled data due to the instability of it*/
    for (i = 0; i < (WATERMARK_VALUE + 1); i++)
    {
      adcswResult[channel][i] = ADC_GetConversionResult(ADC0_ID);
      ADC0_BUFF[channel][i] = adcswResult[channel][i];
      //dataswResult[channel][i] = adcswResult[channel][i] & 0xfff;
      //chswResult[channel][i] = (adcswResult[channel][i] >> 12) & 0x1f;
    }
    /* 累积采样次数，如果满足采样次数，终止采样，标记采样完成 */
    ++ADC0_SampleCount;
		if(ADC0_SampleCount >= 4)
		{
			ADC0_SampleCount = 0;       /* 清通道计数器 */
			ADC0_CompleteFlag = 1;      /* 标记采样完成 */
		}
  }
  ADC_IntClear(ADC0_ID, ADC_FWM_INT);
}
void Four_channelADC_init(channel_ADC channel)
{
  /* Reset ADC */
  SYSCTRL_ResetModule(SYSCTRL_ADC0);
  /* Enable ADC clock */
  SYSCTRL_EnableModule(SYSCTRL_ADC0);
  /* Register the callback function */
  ADC_InstallCallBackFunc(ADC0_ID, ADC_FWM_INT, adc_sw_tcomp_cb); // ADC_TCOMP_INT

  /* Reset software */
  ADC_SoftwareReset(ADC0_ID);
  /* Initialize ADC */
  ADC_Init(ADC0_ID, &adcCfg);
  /*Configure the FIFO depth*/
  ADC_FifoDepthRedefine(ADC0_ID, 16);
  /* Set ADC watermark*/
  ADC_FifoWatermarkConfig(ADC0_ID, 10);
  PORT_PinmuxConfig(port_adc[channel].PORT, port_adc[channel].GPIO, port_adc[channel].PT);
  /* Channel configurate */
  ADC_ChannelConfig(ADC0_ID, &adcswChannelCfg[channel]); //!!

  /* Only unmask TCOMP interrupt */
  ADC_IntMask(ADC0_ID, ADC_INT_ALL, MASK);
  ADC_IntMask(ADC0_ID, ADC_FWM_INT, UNMASK); //   ADC_TCOMP_INT
  /* Clear TCOMP interrupt */
  ADC_IntClear(ADC0_ID, ADC_FWM_INT);
  /* Enable ADC */
  ADC_Enable(ADC0_ID);
  /* Enable ADC interrupt */
  NVIC_EnableIRQ(ADC0_IRQn);
}
void low_adc_sw_clock_init(void)
{
  /* Select clock source for ADC. Selection of ADC functional clock is suggested to be the same with bus clock*/
  CLK_ModuleSrc(CLK_ADC0, CLK_SRC_FIRC64M);
  /*set clock for ADC , make sure it is not greater than bus clock*/
  CLK_SetClkDivider(CLK_ADC0, CLK_DIV_2);

  /* Reset ADC */
  SYSCTRL_ResetModule(SYSCTRL_ADC0);
  /* Enable ADC clock */
  SYSCTRL_EnableModule(SYSCTRL_ADC0);
  /* Select clock source for PORTB and enable */
}
void low_adc_sw_init(void)
{
  /* Register the callback function */
  ADC_InstallCallBackFunc(ADC0_ID, ADC_FWM_INT, adc_sw_tcomp_cb); // ADC_TCOMP_INT
  /* Reset software */
  ADC_SoftwareReset(ADC0_ID);
  /* Initialize ADC */
  ADC_Init(ADC0_ID, &adcCfg);
  /*Configure the FIFO depth*/
  ADC_FifoDepthRedefine(ADC0_ID, 16);
  /* Set ADC watermark*/
  ADC_FifoWatermarkConfig(ADC0_ID, 10);
  /* Channel configurate */
  ADC_ChannelConfig(ADC0_ID, &adcswChannelCfg[0]);
  /* Only unmask TCOMP interrupt */
  ADC_IntMask(ADC0_ID, ADC_INT_ALL, MASK);
  ADC_IntMask(ADC0_ID, ADC_FWM_INT, UNMASK);
  /* Clear TCOMP interrupt */
  ADC_IntClear(ADC0_ID, ADC_FWM_INT);
  /* Enable ADC */
  ADC_Enable(ADC0_ID);
  /* Enable ADC interrupt */
  NVIC_EnableIRQ(ADC0_IRQn);
  // ADC_SoftwareTrigger(ADC0_ID);
}
void Adc_Sw_Channel_switching(void)
{
  static uint32_t receive_timer20ms = 0; // 20ms计数器
  static uint32_t receive_timer1ms = 0;  // 1ms计数器
  static uint8_t Trigger_Counter = 0;    // ADC触发采样计数器
  if ( NO == ADC0_CompleteFlag && Get1MsTickInterval(receive_timer20ms, 20) == YES)
  {
    // GPIO_TogglePinOutput(PORT_B, GPIO_5);//反转电平测试
    receive_timer20ms = Get1MsTickVal();
    channel++;
    if (channel == 4)
    {
      channel = ADC_CH4;
    }
    Four_channelADC_init(channel);
    /* Software trigger */
    Trigger_Counter = 0;
  }
  else
  {
    if (NO == ADC0_CompleteFlag && Get1MsTickInterval(receive_timer1ms, 1) == YES)
    {
      receive_timer1ms = Get1MsTickVal();
      if (Trigger_Counter < 10)
      {
        ADC_SoftwareTrigger(ADC0_ID);
        Trigger_Counter++;
      }
    }
  }
  low_AnalSiglPro_CalculSum(); /* 模拟信号计算 */
}

/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓应用层函数定义开始↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
#if 1

/*
**********************************************************
*name: AnalSiglPro_CalculSum
*descripiton: 模拟信号处理 计算初始化采样信号的和值和最值
**********************************************************
*/
void low_AnalSiglPro_CalculSum(void)
{
#define LOW_SUMDATANUM (sizeof(low_ADC_ORIG_DATA_struct) / sizeof(ADC_ORIG_DATA_TYPE_DEF)) /*数据个数 */

#define GET_MAX(max, a, d)           \
  {                                  \
    (max) = ((a) > (d)) ? (a) : (d); \
  }
#define GET_MiM(min, a, d)           \
  {                                  \
    (min) = ((a) < (d)) ? (a) : (d); \
  }

  ADC_ORIG_DATA_TYPE_DEF *ptr = &(low_ADC_OrgiData.PCB_temp);
  uint32_t sum[LOW_SUMDATANUM];
  uint16_t max[LOW_SUMDATANUM];
  uint16_t min[LOW_SUMDATANUM];
  uint16_t i, j;
  uint16_t tmp;

  /* 如果正在采样，退出 */
  if (NO == ADC0_CompleteFlag)
  {
    ;
    ;
    ;
  }
  else
  {
    /* 初始化缓存区 */
    for (i = 0; i < LOW_SUMDATANUM; i++)
    {
      sum[i] = 0;
      max[i] = 0;
      min[i] = 0xffff;
    }

    /*累计求和，求最大值，求最小值 */
    for (i = 0; i < LOW_ADC0_BUFF_LEN; i++)
    {
      for (j = 0; j < LOW_SUMDATANUM; j++)
      {
        (ptr + j)->wave[i] = ADC0_BUFF[j][i]; /* 记录原始数据 */
        sum[j] += (ptr + j)->wave[i];         /* 累和 */

        tmp = max[j];
        GET_MAX(max[j], tmp, (ptr + j)->wave[i]); /* 求最大值 */
        tmp = min[j];
        GET_MiM(min[j], tmp, (ptr + j)->wave[i]); /* 求最小值 */
      }
    }

    /*更新数据 */
    for (j = 0; j < LOW_SUMDATANUM; j++)
    {
      (ptr + j)->sum = (uint16_t)sum[j];
      (ptr + j)->max = max[j];

      (ptr + j)->min = min[j];

      (ptr + j)->avg =
          ((ptr + j)->sum - (ptr + j)->max - (ptr + j)->min) / (ADC0_BUFF_LEN - 2u);
    }

    ADC0_CompleteFlag = NO; /* 清 采样完成标志 */
                            // ADC0_Start();                                                           /* 启动 ADC 采样 */
    //        DBG_ADC_PRINT_ORGI_DATA();                                              /* 调试 打印 采样信息*/
  }
}
#endif
/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑应用层函数定义结束↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/